/**
 * Created by 51ibm on 2015/6/25.
 */
/*
 * Tetris with jQuery - 2006/06/25
 *   see: http://en.wikipedia.org/wiki/Category:Tetris
 *        http://en.wikipedia.org/wiki/Tetris_Worlds
 *   be careful: http://en.wikipedia.org/wiki/Tetris_effect
 * Copyright (c) 2006 Franck Marcia
 * Licensed under the MIT License:
 *   http://www.opensource.org/licenses/mit-license.php
 */

var tetris = {

    // Shape colors
    //形状颜色
    colors: ['#eaeaea','#ff6600','#eec900','#0000ff',
        '#cc00ff','#00ff00','#66ccff','#ff0000'],

    // Starting line for each shape
    //每种形状开始的线
    startAt: [0, -1, -1, -1, 0, -1, -1, 0],

    // Points per number of lines
    //下标表示炸掉的函数，值对应分数
    points: [0, 40, 100, 300, 1200],

    // Combination of each shape
    //每种形状的不同变化形式的集合
    shapes: [
        // none
        [],
        // I
        [[[0,0,0,0],[1,1,1,1],[0,0,0,0],[0,0,0,0]],
            [[0,1,0,0],[0,1,0,0],[0,1,0,0],[0,1,0,0]]],
        // T
        [[[0,0,0,0],[1,1,1,0],[0,1,0,0],[0,0,0,0]],
            [[0,1,0,0],[1,1,0,0],[0,1,0,0],[0,0,0,0]],
            [[0,1,0,0],[1,1,1,0],[0,0,0,0],[0,0,0,0]],
            [[0,1,0,0],[0,1,1,0],[0,1,0,0],[0,0,0,0]]],
        // L
        [[[0,0,0,0],[1,1,1,0],[1,0,0,0],[0,0,0,0]],
            [[1,1,0,0],[0,1,0,0],[0,1,0,0],[0,0,0,0]],
            [[0,0,1,0],[1,1,1,0],[0,0,0,0],[0,0,0,0]],
            [[0,1,0,0],[0,1,0,0],[0,1,1,0],[0,0,0,0]]],
        // J
        [[[1,0,0,0],[1,1,1,0],[0,0,0,0],[0,0,0,0]],
            [[0,1,1,0],[0,1,0,0],[0,1,0,0],[0,0,0,0]],
            [[0,0,0,0],[1,1,1,0],[0,0,1,0],[0,0,0,0]],
            [[0,1,0,0],[0,1,0,0],[1,1,0,0],[0,0,0,0]]],
        // Z
        [[[0,0,0,0],[1,1,0,0],[0,1,1,0],[0,0,0,0]],
            [[0,0,1,0],[0,1,1,0],[0,1,0,0],[0,0,0,0]]],
        // S
        [[[0,0,0,0],[0,1,1,0],[1,1,0,0],[0,0,0,0]],
            [[0,1,0,0],[0,1,1,0],[0,0,1,0],[0,0,0,0]]],
        // O
        [[[0,1,1,0],[0,1,1,0],[0,0,0,0],[0,0,0,0]]]],

    // Pre-load elements of the grid
    //初始化游戏表格布局
    init: function() {
        var i, j, k;
        tetris.cells = [];
        for (i = -3; i < 18; ++i) {
            tetris.cells[i] = [];
            for (j = 1; j < 11; ++j) {
                k = String.fromCharCode(i + 97);
                tetris.cells[i][j] = $(['#', k, j].join(''));
            }
        }
        tetris.bound = $.browser == 'msie' ? '#tetris' : window;
    },

    // Initialize to start the game
    //开始游戏
    start: function() {
        // Stats
        tetris.level = 0;
        tetris.lines = 0;
        tetris.score = 0;
        // Array which contains data of the grid
        tetris.grid = [
            [1,0,0,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,0,0,1],
            [1,0,0,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,0,0,1],
            [1,0,0,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,0,0,1],
            [1,0,0,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,0,0,1],
            [1,0,0,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,0,0,1],
            [1,0,0,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,0,0,1],
            [1,0,0,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,0,0,1],
            [1,0,0,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,0,0,1],
            [1,0,0,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,0,0,1],
            [1,1,1,1,1,1,1,1,1,1,1,1]];
        //为表格设置背景颜色
        $('#grid td').css('backgroundColor', tetris.colors[0]);
        //如果已经点击了按钮，则状态设为resume，否则状态为start
        $('#start').unclick(tetris.start).val('pause').click(tetris.pause);
        $('#stop').set('disabled', false);
        //键盘事件
        $(tetris.bound).keypress(tetris.key);
        //随机生成下一种落下的形状
        tetris.next = tetris.newShape();
        tetris.shift();
        //设置方块落下时延迟的时间
        tetris.duration = 600;

        tetris.refresh();
        //每隔600毫秒就执行方块的下落函数
        tetris.timer = window.setInterval(tetris.moveDown, tetris.duration);
    },

    // Define the action to be fired depending on key entry
    //键盘的事件监听
    key: function(e) {
        switch(e.charCode || e.keyCode) {
            case 74: case 106: tetris.moveLeft(); break; // J
            case 76: case 108: tetris.moveRight(); break; // L
            case 75: case 107: tetris.moveDown(); break; // K
            case 73: case 105: tetris.rotate(); break; // I
        }
        return false;
    },

    // Generate an random shape
    //随机生成一种形状
    newShape: function() {
        var r = 1 + Math.random() * 7;
        return parseInt(r > 7 ? 7 : r, 10);
    },

    // Define then draw the next shape
    //定义接下来掉下来的形状
    setNext: function() {
        var i, j, s, c, d, n = tetris.colors[0];
        tetris.next = tetris.newShape();
        s = tetris.shapes[tetris.next][0];
        c = tetris.colors[tetris.next];
        for (i = 0; i < 4; ++i) {
            for (j = 0; j < 4; ++j) {
                d = s[i][j] ? c : n;
                $(['#x', j, i].join('')).css('backgroundColor', d);
            }
        }
    },

    // The next shape becomes the current one; reset coordinates
    //下一个形状变成当前，如何绘制下一个形状
    shift: function() {
        tetris.cur = tetris.next;
        tetris.x = tetris.x0 = 4;
        tetris.y = tetris.startAt[tetris.cur];
        tetris.y0 = tetris.y - 2;
        tetris.r = tetris.r0 = 0;
        tetris.curShape = tetris.shapes[tetris.cur];
        if (tetris.canGo(0, tetris.x, tetris.y)) {
            tetris.setNext();
            return true;
        }
        return false;
    },

    // Pause the game
    //游戏暂停
    pause: function() {
        //注销键盘的事件监听
        $(tetris.bound).unkeypress(tetris.key);
        //暂停方块下降
        window.clearInterval(tetris.timer);
        tetris.timer = null;
        //切换开始按钮的点击状态
        $('#start').unclick(tetris.pause).val('resume').click(tetris.resume);
    },

    // Resume the game
    //恢复游戏
    resume: function() {
        //注册键盘的事件监听
        $(tetris.bound).keypress(tetris.key);
        //恢复方块的下降
        tetris.timer = window.setInterval(tetris.moveDown, tetris.duration);
        //切换开始按钮的点击状态
        $('#start').unclick(tetris.resume).val('pause').click(tetris.pause);
    },

    // Stop the game
    //停止游戏
    gameOver: function() {
        var i, j;
        // Manage buttons
        //将游戏循环下落方块的效果关闭掉,简单地说就是停止循环
        if (tetris.timer) {
            $(tetris.bound).unkeypress(tetris.key);
            window.clearInterval(tetris.timer);
            tetris.timer = null;
            //将开始按钮设置为start状态
            $('#start').unclick(tetris.pause).val('start').click(tetris.start);
        } else {
            $('#start').unclick(tetris.resume).val('start').click(tetris.start);
        }
        //将stop按钮设置为不可用
        $('#stop').set('disabled', true);
        // Draw everything in white
        //将游戏方块变成灰色
        for (i = 0; i < 18; ++i) {
            for (j = 1; j < 11; ++j) {
                if (tetris.grid[i][j]) {
                    tetris.cells[i][j].css('backgroundColor', '#cccccc');
                }
            }
        }
        //将方块绘制成灰色
        tetris.draw(tetris.r0, tetris.x0, tetris.y0, '#cccccc');
    },

    // Check overlays
    //判断是否可以移动或改变形状
    canGo: function(r, x, y) {
        var i, j;
        for (i = 0; i < 4; ++i) {
            for (j = 0; j < 4; ++j) {
                if (tetris.curShape[r][j][i] && tetris.grid[y + j] &&
                    tetris.grid[y + j][x + i]) {
                    return false;
                }
            }
        }
        return true;
    },

    // Move the current shape to the left
    //左移
    moveLeft: function() {
        if (tetris.canGo(tetris.r, tetris.x - 1, tetris.y)) {
            --tetris.x;
            tetris.refresh();
        }
    },

    // Move the current shape to the right
    //右移
    moveRight: function() {
        if (tetris.canGo(tetris.r, tetris.x + 1, tetris.y)) {
            ++tetris.x;
            tetris.refresh();
        }
    },

    // Rotate the current shape
    //改变当前的形状
    rotate: function() {
        var r = tetris.r == tetris.curShape.length - 1 ? 0 : tetris.r + 1;
        if (tetris.canGo(r, tetris.x, tetris.y)) {
            tetris.r0 = tetris.r;
            tetris.r = r;
            tetris.refresh();
        }
    },

    // Move down the current shape
    //下移
    moveDown: function() {
        if (tetris.canGo(tetris.r, tetris.x, tetris.y + 1)) {
            ++tetris.y;
            tetris.refresh();
        } else {
            tetris.touchDown();
        }
    },

    // The current shape touches down
    //径直落下
    touchDown: function() {
        var i, j, k, r, f;
        // mark the grid
		//将方块的位置，形状等相关的数据记录下来
        for (i = 0; i < 4; ++i) {
            for (j = 0; j < 4; ++j) {
                if (tetris.curShape[tetris.r][j][i] &&
                    tetris.grid[tetris.y + j]) {
                    tetris.grid[tetris.y + j][tetris.x + i] = tetris.cur;
                }
            }
        }
        // search complete lines
		//判断方块下落后与周边的方块是否有形成一条直线
        f = 0;
        for (i = 17, k = 17; i > -1 && f < 4; --i, --k) {
            if (tetris.grid[i].join('').indexOf('0') == -1) {
                // Complete lines become white
				//将已经拼好的方块线去除
                for (j = 1; j < 11; ++j) {
                    tetris.cells[k][j].css('backgroundColor', '#cccccc');
                }
                ++f;
                for (j = i; j > 0; --j) {
                    tetris.grid[j] = tetris.grid[j - 1].concat();
                }
                ++i;
            }
        }
        // animate
		//设置循环的速度
        if (f) {
            window.clearInterval(tetris.timer);
            tetris.timer = window.setTimeout(function(){tetris.after(f);}, 100);
        }
        // try to continue
		//改变游戏状态，或开始，或结束
        if (tetris.shift()) {
            tetris.refresh();
        } else {
            tetris.gameOver();
        }
    },

    // Finish the touchdown process
    after: function(f) {
        var i, j, l = (tetris.level < 20 ? tetris.level : 20) * 25;
        // stats
        //统计lines
        tetris.lines += f;
        //计算level
        if (tetris.lines % 10 === 0) {
            tetris.level = tetris.lines / 10;
        }
        window.clearTimeout(tetris.timer);
        tetris.timer = window.setInterval(tetris.moveDown, tetris.duration - l);
        //统计分数
        tetris.score += (tetris.level + 1) * tetris.points[f];
        // redraw the grid
        for (i = 0; i < 18; ++i) {
            for (j = 1; j < 11; ++j) {
                tetris.cells[i][j].css('backgroundColor',
                    tetris.colors[tetris.grid[i][j]]);
            }
        }
        tetris.refresh();
    },

    // Draw the current shape
	//画出当前的形状
    draw: function(r, x, y, c) {
        var i, j;
        for (i = 0; i < 4; ++i) {
            for (j = 0; j < 4; ++j) {
                if (tetris.curShape[r][j][i]) {
                    tetris.cells[y + j][x + i].css('backgroundColor', c);
                }
            }
        }
    },

    // Refresh the grid
    //重置游戏布局表格
    refresh: function() {
        // remove from the old position
        tetris.draw(tetris.r0, tetris.x0, tetris.y0, tetris.colors[0]);
        // draw to the next one
        tetris.draw(tetris.r, tetris.x, tetris.y, tetris.colors[tetris.cur]);
        // change stats
        $('#level').html(tetris.level + 1);
        $('#lines').html(tetris.lines);
        $('#score').html(tetris.score);
        // reset coordinates
        tetris.x0 = tetris.x;
        tetris.y0 = tetris.y;
        tetris.r0 = tetris.r;
    }

};

// Everything starts here
//游戏的开始，作初始化的工作
$(window).load(function() {
    tetris.init();
    //为表格设置背景色
    $('#grid table, #next table').css('backgroundColor', tetris.colors[0]);
    //为开始和停止按钮添加事件监听
    $('#start').click(tetris.start);
    $('#stop').click(tetris.gameOver);
});